package com.xyzh05.service.impl;

import java.util.ArrayList;
import java.util.List;

import javax.jws.WebService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.orm.jpa.JpaSystemException;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import com.xyzh05.dao.UserDao;
import com.xyzh05.model.User;
import com.xyzh05.service.UserExistsException;
import com.xyzh05.service.UserManager;
import com.xyzh05.service.UserService;
import com.xyzh05.util.ConvertUtil;
import com.xyzh05.util.PageBean;


/**
 * Implementation of UserManager interface.
 *
 * @author <a href="mailto:matt@raibledesigns.com">Matt Raible</a>
 */
@Service("userManager")
@WebService(serviceName = "UserService", endpointInterface = "com.xyzh05.service.UserService")
public class UserManagerImpl extends GenericManagerImpl<User, Long> implements UserManager, UserService {
    private PasswordEncoder passwordEncoder;
    private UserDao userDao;
    
    @Autowired
    public UserManagerImpl(UserDao userDao) {
        super(userDao);
        this.userDao = userDao;
    }

    @Autowired
    public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }

    @Autowired
    public void setUserDao(UserDao userDao) {
        this.dao = userDao;
        this.userDao = userDao;
    }

    /**
     * {@inheritDoc}
     */
    public User getUser(String userId) {
        return userDao.get(new Long(userId));
    }

    /**
     * {@inheritDoc}
     */
    public List<User> getUsers() {
        return userDao.getAllDistinct();
    }

    /**
     * {@inheritDoc}
     */
    public User saveUser(User user) throws UserExistsException {
        // Get and prepare password management-related artifacts
        if (passwordEncoder != null) {
            user.setPassword(passwordEncoder.encodePassword(user.getPassword(), null));
            //user.setPassword(ConvertUtil.String2Hex(user.getUsername(), user.getPassword()));
        } else {
            log.warn("PasswordEncoder not set, skipping password encryption...");
        }

        try {
            return userDao.saveUser(user);
        } catch (DataIntegrityViolationException e) {
            log.warn(e.getMessage());
            throw new UserExistsException("User '" + user.getUsername() + "' already exists!");
        } catch (JpaSystemException e) { 
        	// needed for JPA
            log.warn(e.getMessage());
            throw new UserExistsException("User '" + user.getUsername() + "' already exists!");
        }
    }

    /**
     * {@inheritDoc}
     */
    public void removeUser(String userId) {
        log.debug("removing user: " + userId);
        userDao.remove(new Long(userId));
    }

    /**
     * {@inheritDoc}
     *
     * @param username the login name of the human
     * @return User the populated user object
     * @throws UsernameNotFoundException thrown when username not found
     */
    public User getUserByUsername(String username) throws UsernameNotFoundException {
        return (User) userDao.loadUserByUsername(username);
    }

    /**
     * {@inheritDoc}
     */
    public List<User> search(String searchTerm) {
        return super.search(searchTerm, User.class);
    }

	public User loadUserByUsernameAndPassword(String username, String password) {
		return userDao.loadUserByUsernameAndPassword(username, password);
	}

	public Boolean userExist(String username) {
		return userDao.userExist(username);
	}
	
	public List<User> queryUserToAutoComplete(String keyword, String level){
		return userDao.queryUserToAutoComplete(keyword, level);
	}
	
	public PageBean showEditors(PageBean pageBean){
		if(pageBean == null){
			pageBean = new PageBean();
		}
		return userDao.queryEditors(pageBean);
	}
	
	public PageBean queryOrdinaryEditor(PageBean pageBean, String major, String nickname){
		if(pageBean == null){
			pageBean = new PageBean();
		}
		List list = new ArrayList();
		StringBuilder hql = new StringBuilder();
		hql.append(" select new User(id, nickname, majorName, registtime, role) from User where bitand(level, 4) != 0 and bitand(level, 32) = 0 ");
		if(major != null && !"".equals(major)){
			String ids = "";
			List<Long> majors = (List<Long>) userDao.findQuery(" select id from Major where name like ? ", "%"+major+"%");	
			ids = majors.toString();
	/*		for(Long id : majors){
				ids += id+",";
			} */
			ids = ids.substring(1, ids.length()-1);
			hql.append(" and major in ("+ids+")");
			 
		}
		if(nickname != null && !"".equals(nickname)){
			hql.append(" and nickname like ? ");
			list.add("%"+nickname+"%");
		}
		return userDao.getPageByHQL(hql.toString(), pageBean, list.toArray());
	}

	public PageBean queryOrdinaryAdviser(PageBean pageBean, String major, String nickname) {
		if(pageBean == null){
			pageBean = new PageBean();
		}
		List list = new ArrayList();
		StringBuilder hql = new StringBuilder();
		hql.append(" select new User(id, nickname, majorName, registtime, role) from User where 1=1 ");
		if(major != null && !"".equals(major)){
			String ids = "";
			List<Long> majors = (List<Long>) userDao.findQuery(" select id from Major where name like ? ", "%"+major+"%");	
			ids = majors.toString();
	/*		for(Long id : majors){
				ids += id+",";
			} */
			ids = ids.substring(1, ids.length()-1);
			hql.append(" and major in ("+ids+")");
			 
		}
		if(nickname != null && !"".equals(nickname)){
			hql.append(" and nickname like ? ");
			list.add("%"+nickname+"%");
		}
		return userDao.getPageByHQL(hql.toString(), pageBean, list.toArray());
	}
}
